#include "StdAfx.h"
#include "Vector3D.h"


CVector3D::CVector3D(void)
: x(0), y(0), z(0)
{
}

CVector3D::CVector3D(DATA_TYPE x, DATA_TYPE y, DATA_TYPE z)
{
	this->x = x;
	this->y = y;
	this->z = z;
}


CVector3D::~CVector3D(void)
{
}

DATA_TYPE CVector3D::Dot(const CVector3D& rhs) const
{
	return this->x * rhs.x +
		   this->y * rhs.y +
		   this->z * rhs.z;
}

CVector3D CVector3D::Cross(const CVector3D& rhs) const
{
	CVector3D ret;
	ret.x = this->y * rhs.z - rhs.y * this->z;
	ret.y = this->z * rhs.x - rhs.z * this->x;
	ret.z = this->x * rhs.y - rhs.x * this->y;
	return ret;
}

DATA_TYPE CVector3D::GetDistance(const CVector3D& rhs) const
{
	DATA_TYPE squaredDist = (x - rhs.x) * (x - rhs.x)
						  + (y - rhs.y) * (y - rhs.y)
						  + (z - rhs.z) * (z - rhs.z);
	return sqrtf(squaredDist);
}

CVector3D CVector3D::operator+(const CVector3D& rhs) const
{
	CVector3D ret;
	ret.x = this->x + rhs.x;
	ret.y = this->y + rhs.y;
	ret.z = this->z + rhs.z;
	return ret;
}

CVector3D CVector3D::operator-(const CVector3D& rhs) const
{
	CVector3D ret;
	ret.x = this->x - rhs.x;
	ret.y = this->y - rhs.y;
	ret.z = this->z - rhs.z;
	return ret;
}

CVector3D CVector3D::operator/(DATA_TYPE fScalar) const
{
	CVector3D ret;
	ret.x = this->x / fScalar;
	ret.y = this->y / fScalar;
	ret.z = this->z / fScalar;
	return ret;
}

CVector3D CVector3D::Normalize() const
{
	DATA_TYPE fNorm = sqrtf(x * x + y * y + z * z);
	CVector3D ret;
	ret.x = x / fNorm;
	ret.y = y / fNorm;
	ret.z = z / fNorm;
	return ret;
}

DATA_TYPE CVector3D::GetLength() const
{
	return sqrtf(x * x + y * y + z * z);
}

DATA_TYPE CVector3D::GetSquareLength() const
{
	return x * x + y * y + z * z;
}

CVector3D CVector3D::GetNormalizedAndLength(DATA_TYPE& fLength) const
{
	fLength = sqrtf(x * x + y * y + z * z);
	CVector3D ret;
	ret.x = x / fLength;
	ret.y = y / fLength;
	ret.z = z / fLength;
	return ret;
}

CVector3D CVector3D::operator-() const
{
	CVector3D ret;
	ret.x = -x;
	ret.y = -y;
	ret.z = -z;
	return  ret;
}

CVector3D operator*(DATA_TYPE fScalar, const CVector3D& vec)
{
	CVector3D ret;
	ret.x = fScalar * vec.x;
	ret.y = fScalar * vec.y;
	ret.z = fScalar * vec.z;
	return ret;
}

DATA_TYPE& CVector3D::operator[](unsigned int idx)
{
	switch (idx)
	{
	case 0:
		return x;
	case 1:
		return y;
	case 2:
		return z;
	default:
		cout << "out of bound\n";
		break;
	}

	return x;
}

DATA_TYPE CVector3D::operator[] (unsigned int idx) const
{
	switch (idx)
	{
	case 0:
		return x;
	case 1:
		return y;
	case 2:
		return z;
	default:
		cout << "out of bound\n";
		break;
	}

	return x;
}